/**
 * 
 */
package com.demo2do.boyle.backend.service.customer.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.demo2do.boyle.backend.Constant;
import com.demo2do.boyle.backend.dao.CustomerMessageDaoSupport;
import com.demo2do.boyle.backend.service.customer.WithdrawalService;
import com.demo2do.boyle.common.entity.aduser.order.PayType;
import com.demo2do.boyle.common.entity.customer.message.Type;
import com.demo2do.boyle.common.entity.customer.wallet.RecordType;
import com.demo2do.boyle.common.entity.customer.wallet.Wallet;
import com.demo2do.boyle.common.entity.customer.wallet.WalletRecord;
import com.demo2do.boyle.common.entity.customer.wallet.Withdrawal;
import com.demo2do.boyle.common.entity.customer.wallet.WithdrawalStatus;
import com.demo2do.core.persistence.GenericDaoSupport;
import com.demo2do.core.service.impl.GenericServiceImpl;
import com.demo2do.core.web.resolver.Page;

/**
 * @author Leo
 *
 */
@Service("withdrawalService")
public class WithdrawalServiceImpl extends GenericServiceImpl<Withdrawal> implements WithdrawalService {
	
	@Autowired
    private GenericDaoSupport genericDaoSupport;
	
	@Autowired
	private CustomerMessageDaoSupport customerMessageDaoSupport;
	
	@SuppressWarnings("unchecked")
	public List<Withdrawal> list(WithdrawalStatus status) {
		if(status == null)
			status = WithdrawalStatus.AUDITING;
		return genericDaoSupport.searchForList("FROM Withdrawal WHERE disabled = false AND status = :status", "status",  status );
	}
	/*
	 * (non-Javadoc)
	 * @see com.demo2do.boyle.backend.service.customer.WithdrawalService#listByStatus(com.demo2do.core.web.resolver.Page, com.demo2do.boyle.common.entity.customer.wallet.WithdrawalStatus)
	 */
	@SuppressWarnings("unchecked")
	public List<Withdrawal> list(WithdrawalStatus status, Page page) {
		if(status == null)
			status = WithdrawalStatus.AUDITING;
		List<Withdrawal> withdrawals = genericDaoSupport.searchForList("FROM Withdrawal WHERE disabled = false AND status = :status", "status",  status, page.getBeginIndex(), page.getMaxResultRecords() );
		page.calculate(withdrawals.size());
		return withdrawals.size() > page.getEveryPage() ? withdrawals.subList(0, page.getEveryPage()) : withdrawals;
	}
	
	public int count(WithdrawalStatus status) {
		if(status == null)
			status = WithdrawalStatus.AUDITING;
		
		Map<String, Object> parameters = new HashMap<String, Object>(1);
		parameters.put("status", status);
		return genericDaoSupport.searchForInt("SELECT COUNT(1) FROM Withdrawal WHERE status = :status", parameters);
	}

	/*
	 * (non-Javadoc)
	 * @see com.demo2do.boyle.backend.service.customer.WithdrawalService#audit(com.demo2do.boyle.common.entity.customer.wallet.Withdrawal)
	 */
	public void audit(Withdrawal withdrawal) {
		
		genericDaoSupport.update(withdrawal.audit());
		
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.demo2do.boyle.backend.service.customer.WithdrawalService#pay(com.demo2do.boyle.common.entity.customer.wallet.Withdrawal)
	 */
	public void batchTransfer(Integer[] ids) {
		
		// 1. batch update withdrawal status
		genericDaoSupport.executeHQL("UPDATE Withdrawal SET status = 3 WHERE id in ( :ids )", "ids", ids);
		
		for(int id : ids) {
			// 2.load withdrawal
			Withdrawal withdrawal = genericDaoSupport.load(Withdrawal.class, id);
			
			// 3. update wallet balance frozenAmount and cashOut 
			Wallet wallet = genericDaoSupport.load(Wallet.class, withdrawal.getCustomer().getId());
			genericDaoSupport.update(wallet.withdrawal(withdrawal.getBalance()));
			
			// 4. create wallet_record
			WalletRecord walletRecord = new WalletRecord(wallet, RecordType.CASH_OUT, PayType.ALIPAY);
			genericDaoSupport.save(walletRecord.initialize(withdrawal.getBalance(), withdrawal.getId()));
			
			// 5 add customer withdrawal success message
			customerMessageDaoSupport.create(withdrawal.getCustomer(), Constant.CUSTOMER_MESSAGE_WITHDRAWAL_SUCCESS, Type.WITHDRAWAL);
			
		}
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.demo2do.boyle.backend.service.customer.WithdrawalService#batchExport(com.demo2do.boyle.common.entity.customer.wallet.WithdrawalStatus)
	 */
	public void batchExport(WithdrawalStatus withdrawalStatus) {
		
		// batch update withdrawal status to PRINTED
		genericDaoSupport.executeHQL("UPDATE Withdrawal SET status = 2 WHERE  status = :status", "status", withdrawalStatus);
		
	}

}
